import { addSurvey, editSurvey, getFollowUpInfo, getSurveyDetail, saveFollowUp } from "@/services/patient/followUpApi";
import { showMsg } from "@/utils/utils";
import { PlusOutlined } from "@ant-design/icons";
import { ModalForm, ProFormInstance, ProFormText, ProFormTextArea } from "@ant-design/pro-form";
import { Button, Card, Checkbox, Col, Divider, Form, Radio, Row, Select } from "antd";
import _ from "lodash";
import { useEffect, useRef, useState } from "react";
import { surveyContent } from './questionnaireForm.less';

const QuestionnaireForm = (props: ModalProps) => {

  const { open, openChange, surveyId, resultInfo, apply, readonly = false } = props;

  const formRef = useRef<ProFormInstance>();
  const [questions, setQuestions] = useState<Question[]>([]);
  const questionType = { 'R': 1, 'C': 2, 'F': 3 };

  useEffect(() => {
    if (readonly && resultInfo) {
      const { order_id, patient_id, survey_id } = resultInfo;
      getFollowUpInfo(patient_id, order_id, survey_id).then(res => {
        const { survey_title, naire_result_list: list } = res;
        console.info(list);
        questionRender(list as PATIENT.Question[]);
        const qFormData = list?.map(({ clas, option_list, option_result_list: resList, question_stem, result }) => ({
          title: question_stem,
          type: questionType[clas],
          value: clas === 'F' ? result : (clas === 'R' ? resList?.[0].option_result : resList?.map(({ option_result }) => option_result)),
          options: clas === 'F' ? undefined : (option_list?.map(({ option_content }) => option_content) ?? [])
        }));
        formRef.current?.setFieldsValue({
          title: survey_title,
          questions: qFormData
        });
      }).catch((err: any) => showMsg(err?.data?.errmsg));
      return;
    }

    const id = apply ? resultInfo?.survey_id : surveyId;
    if (id) {
      getSurveyDetail(id).then(({ survey_title, question_list }) => {
        questionRender(question_list);
        const qFormData = question_list.map(({ clas, question_id, question_stem, option_list }) => ({
          id: question_id,
          title: question_stem,
          type: questionType[clas],
          options: clas === 'F' ? undefined : (option_list.map(({ option_content }) => option_content) ?? [])
        }));
        formRef.current?.setFieldsValue({
          title: survey_title,
          questions: qFormData
        });
      }).catch((err: any) => showMsg(err?.data?.errmsg));
    }
  }, [surveyId, resultInfo]);

  const questionRender = (list: PATIENT.Question[]) => {
    const qList = list.map(({ clas, option_list }, qKey) => ({
      key: qKey,
      type: questionType[clas] as any,
      options: option_list?.map(({ option_id, option_content }, opKey) => ({
        key: opKey, text: option_content, id: option_id
      }))
    }));
    setQuestions(qList);
  };

  const onFinish = async (values: FormType) => {
    if (readonly) {
      openChange(false);
      return;
    }
    if (apply) {
      await submitFollowUp(values);
    } else {
      await saveSurvey(values);
    }
  }

  /**
   * 保存随访填写数据
   */
  const submitFollowUp = async ({ questions }: FormType) => {
    console.info(questions);
    const { order_id, patient_id, survey_id } = resultInfo ?? {};
    const result = questions?.map(({ id, type, value }, idx) => {
      const obj = { question_id: id };
      if (type === 3) {
        obj['result'] = value;
      } else {
        obj['option_list'] = Array.isArray(value)
          ? value.map(oId => ({
            option_id: oId,
            option_result: oId
          }))
          : [{
            option_id: value,
            option_result: value
          }];
      }
      return obj;
    });
    try {
      await saveFollowUp({ survey_test_id: survey_id, order_id, patient_id, survey_result: result });
      showMsg('填写成功', 'success');
      openChange(false);
    } catch (error: any) {
      showMsg(error?.data?.errmsg);
    }
  };

  /**
   * 保存调研表数据
   */
  const saveSurvey = async (values: FormType) => {
    const qList = values.questions?.filter(elem => !!elem) ?? [];
    if (qList.length === 0) {
      showMsg('请添加调研问题');
      return;
    }
    for (const { type, options } of qList) {
      if (type !== 3 && (options?.filter(elem => !!elem) ?? []).length === 0) {
        showMsg('请添加问题的回答选项');
        return;
      }
    }
    const questionType = { 1: 'R', 2: 'C', 3: 'F' };
    const question_list = qList.map(({ title, type, options }) => ({
      question_stem: title,
      clas: questionType[type] as any,
      option_list:
        type === 3
          ? []
          : options?.filter(elem => !!elem).map(elem => ({ is_add: 'N' as any, option_content: elem })) ?? []
    }));
    const data = { survey_title: values.title, question_list };
    try {
      if (surveyId) {
        await editSurvey(surveyId, data);
      } else {
        await addSurvey(data);
      }
      showMsg('保存成功', 'success');
      openChange(false);
    } catch (error: any) {
      showMsg(error?.data?.errmsg);
    }
  };

  /** 添加问题 */
  const addQuestion = () => {
    const preKey = questions.slice(-1)[0]?.key ?? 0;
    setQuestions([...questions, { key: preKey + 1 }]);
  };

  /** 删除问题 */
  const deleteQuestion = (questionKey: number) => {
    const { qs, qIdx } = commonData(questionKey);
    qs.splice(qIdx, 1);
    setQuestions(qs);
    formRef.current?.resetFields([['questions', questionKey]]);
  };

  /** 问题类型变更 */
  const questionTypeChange = (questionKey: number, selectValue: any) => {
    const { qs, currQ } = commonData(questionKey);
    currQ.type = selectValue;
    currQ.options = selectValue === 3 ? undefined : [];
    setQuestions(qs);
    formRef.current?.resetFields([['questions', questionKey, 'options'], ['questions', questionKey, 'value']]);
  };

  /** 添加选项 */
  const addOption = (questionKey: number) => {
    const { qs, currQ } = commonData(questionKey);
    if (currQ.options instanceof Array) {
      const preKey = currQ.options.slice(-1)[0]?.key ?? 0;
      currQ.options.push({ key: preKey + 1 });
    } else {
      currQ.options = [{ key: 1 }];
    }
    setQuestions(qs);
  };

  /** 删除选项 */
  const deleteOption = (questionKey: number, optionKey: number) => {
    const { qs, currQ } = commonData(questionKey);
    if (currQ.options instanceof Array) {
      const opIdx = currQ.options.findIndex(op => op.key === optionKey);
      currQ.options.splice(opIdx, 1);
      formRef.current?.resetFields([['questions', questionKey, 'options', optionKey]]);
    }
    setQuestions(qs);
  };

  /** 复制原始数据 */
  const commonData = (questionKey: number) => {
    const qs = [...questions];
    const qIdx = qs.findIndex(q => q.key === questionKey);
    const currQ = _.cloneDeep(qs[qIdx]);
    qs[qIdx] = currQ;
    return { qs, qIdx, currQ };
  };

  return (
    <ModalForm
      formRef={formRef}
      width={600} layout="horizontal"
      visible={open} onVisibleChange={visible => { if (!visible) { setQuestions([]); } openChange(visible); }}
      modalProps={{ maskClosable: false, destroyOnClose: true }}
      onFinish={onFinish}
    >
      <Card bordered={false} bodyStyle={{ padding: '30px 24px 12px 4px' }} style={{ borderBottom: '1px solid #aaa' }}>
        {
          apply ? <div style={{ fontSize: 16, fontWeight: 600 }}><ProFormText name="title" readonly noStyle /></div> :
            <ProFormText
              name="title" label="调研表名称" readonly={readonly}
              labelCol={{ flex: '0 0 86px' }} wrapperCol={{ span: 19 }}
              rules={[{ required: true }]}
            />
        }
      </Card>
      <Card bordered={false} bodyStyle={{ padding: '18px 24px 12px 18px', maxHeight: 500, overflowY: "scroll" }} className={surveyContent}>
        {
          questions?.map(({ key: qKey, type, options }, idx) => (
            <div key={`q${qKey}`}>
              {idx === 0 ? <></> : <Divider style={{ borderTop: '1px solid #ccc' }} />}
              <div>
                <Row style={{ alignItems: "center" }}>
                  <Col flex={'1 0 auto'}>
                    <ProFormText name={['questions', qKey, `title`]} readonly={readonly || apply}
                      label={`问题${idx + 1}`} labelCol={{ flex: '0 0 72px' }}
                      formItemProps={{ style: { marginBottom: 0 } }} rules={apply ? undefined : [{ required: true }]}
                    />
                    <ProFormText name={['questions', qKey, `type`]} hidden readonly noStyle />
                    <ProFormText name={['questions', qKey, `id`]} hidden readonly noStyle />
                  </Col>
                  {
                    !apply &&
                    <Col style={{ marginLeft: 6, userSelect: "none" }}>
                      <a style={{ fontSize: 12 }} onClick={() => deleteQuestion(qKey)}>删除</a>
                    </Col>
                  }
                </Row>
                {
                  apply ? <></> :
                    <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                      <Form.Item name={['questions', qKey, `type`]}
                        label="问题类型" labelCol={{ flex: '0 0 72px' }}
                        style={{ flex: '1 0 auto', marginBottom: 0 }}
                        rules={[{ required: true, message: '请选择问题类型' }]}
                      >
                        <Select options={questionTypeOptions} onChange={value => questionTypeChange(qKey, value)} placeholder="请选择" />
                      </Form.Item>
                      {
                        (type === 1 || type === 2) &&
                        <div>
                          <a onClick={() => addOption(qKey)} style={{ userSelect: "none", fontSize: 12 }}>增加选项</a>
                        </div>
                      }
                    </div>
                }
                {
                  !(type === 3 && apply) ? <></> :
                    <ProFormTextArea name={['questions', qKey, `value`]} label="回答" labelCol={{ flex: '0 0 72px' }} readonly={readonly} />
                }
                {
                  !(type === 2) ? <></> :
                    <Form.Item name={['questions', qKey, 'value']}>
                      <Checkbox.Group name={`chk_${qKey}`} style={{ display: 'grid', flexGrow: 1, rowGap: 6 }} disabled={readonly}>
                        {
                          options?.map(({ key: opKey, text, id }) => (
                            <Row key={`q${qKey}_op${opKey}`} style={{ alignItems: "center" }}>
                              <Col flex='0 0 48px' />
                              <Col><Checkbox value={apply ? id : opKey} style={{ marginRight: 8 }}>{apply ? text : undefined}</Checkbox></Col>
                              {
                                apply ? <></> : <>
                                  <Col style={{ flexGrow: 1 }}>
                                    <ProFormText name={['questions', qKey, 'options', opKey]}
                                      formItemProps={{ style: { marginBottom: 0 } }}
                                      rules={[{ required: true, message: '请输入回答选项的文本' }]}
                                    />
                                  </Col>
                                  <Col style={{ marginLeft: 12 }}>
                                    <a style={{ fontSize: 12, userSelect: "none" }} onClick={() => deleteOption(qKey, opKey)}>删除</a>
                                  </Col>
                                </>
                              }
                            </Row>
                          ))
                        }
                      </Checkbox.Group>
                    </Form.Item>
                }
                {
                  !(type === 1) ? <></> :
                    <Form.Item name={['questions', qKey, 'value']}>
                      <Radio.Group name={`rdo_${qKey}`} style={{ display: 'grid', flexGrow: 1, rowGap: 6 }} disabled={readonly}>
                        {
                          options?.map(({ key: opKey, text, id }) => (
                            <Row key={`q${qKey}_op${opKey}`} style={{ alignItems: "center" }}>
                              <Col flex='0 0 48px' />
                              <Col><Radio value={apply ? id : opKey}>{apply ? text : undefined}</Radio></Col>
                              {
                                apply ? <></> : <>
                                  <Col style={{ flexGrow: 1 }}>
                                    <ProFormText name={['questions', qKey, 'options', opKey]}
                                      formItemProps={{ style: { marginBottom: 0 } }}
                                      rules={[{ required: true, message: '请输入回答选项的文本' }]}
                                    />
                                  </Col>
                                  <Col style={{ marginLeft: 12 }}>
                                    <a style={{ fontSize: 12, userSelect: "none" }} onClick={() => deleteOption(qKey, opKey)}>删除</a>
                                  </Col>
                                </>
                              }
                            </Row>
                          ))
                        }
                      </Radio.Group>
                    </Form.Item>
                }
              </div>
            </div>
          ))
        }
      </Card>
      {
        apply ? <></> : <Button icon={<PlusOutlined />} style={{ width: "100%" }} className="ant-btn-dashed" onClick={() => addQuestion()}>添加一个问题</Button>
      }
      <div style={{ height: 6 }}></div>
    </ModalForm>
  );
};

export default QuestionnaireForm;

interface ModalProps {
  open: boolean;
  openChange: (open: boolean) => void;
  /**
   * 只读模式
   */
  readonly?: boolean;
  /**
   * true:使用随访表, false:新增修改随访表
   */
  apply: boolean;
  /**
   * 调研表ID
   */
  surveyId?: string;
  /**
   * 调研结果信息
   */
  resultInfo?: ResultInfo;
};

export interface ResultInfo {
  patient_id: string;
  order_id: string;
  survey_id: string;
};

type Question = {
  key: number,
  type?: 1 | 2 | 3, // 1:单选、2:多选、3:填写
  // 包含的选项
  options?: {
    key: number;
    text?: string;
    id?: string;
  }[]
};

const questionTypeOptions = [
  { label: '单选', value: 1 },
  { label: '多选', value: 2 },
  { label: '填写', value: 3 }
];

type FormType = {
  title: string;
  questions: Array<
    {
      id?: string;
      title: string;
      type: 1 | 2 | 3;
      options: Array<string> | undefined;
      value: any;
    }
  > | undefined;
};
